package com.hq.ims.data.service;

import com.hq.ims.data.alisms.AliSmsConfig;
import com.hq.ims.data.dao.BusInfoForewarningMapper;
import com.hq.ims.data.entity.*;
import com.hq.ims.data.entityenum.EnumFeedbackPhase;
import com.hq.ims.data.entityenum.EnumForewarningInfoClassify;
import com.hq.ims.data.job.ForewarningJob;
import com.hq.ims.data.quartz.utils.QuartzUtils;
import com.hq.ims.data.vo.BusInfoForewarningMapstruct;
import com.hq.ims.data.vo.BusiIndustryAssignMapstruct;
import com.hq.mybatis.base.BaseService;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.utils.util.JsonUtils;
import com.hq.utils.util.ListUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 蒋柏平
 * @detail 经营信息预警表 服务实现类
 * @since 20241114
 */
@Service
@Slf4j
public class BaseBusInfoForewarningService extends BaseService<BusInfoForewarningMapper, BusInfoForewarning> {

    @Resource
    private BusInfoForewarningMapper busInfoForewarningMapper;
    @Resource
    private BaseBusiInfoService baseBusiInfoService;
    @Resource
    private BaseBusForewarningSetService baseBusForewarningSetService;
    @Resource
    private BaseBusInfoTrackService baseBusInfoTrackService;
    @Resource
    private BaseCompanyEmployeeService baseCompanyEmployeeService;
    @Resource
    private SchedulerFactoryBean schedulerFactoryBean;
    @Resource
    private AliSmsConfig aliSmsConfig;

    /**
     * 经营信息预警分页查询
     *
     * @param page     分页对象
     * @param searchVo 查询条件
     */
    public void getByPage(RequestPage<BusInfoForewarningMapstruct.BusInfoForewarningVo> page,
                          BusInfoForewarningMapstruct.PageSearchVo searchVo) {
        page = busInfoForewarningMapper.pageList(page, searchVo);
        List<BusInfoForewarningMapstruct.BusInfoForewarningVo> busInfoForewarningVoList = page.getRecords();
        forewarningEndDateCompute(busInfoForewarningVoList);
        page.setRecords(busInfoForewarningVoList);
    }

    /**
     * 查询预警信息-不分页
     *
     * @param searchVo 查询条件
     */
    public List<BusInfoForewarningMapstruct.BusInfoForewarningVo> getBusInfoForewarningList(BusInfoForewarningMapstruct.PageSearchVo searchVo) {
        List<BusInfoForewarningMapstruct.BusInfoForewarningVo> busInfoForewarningVoList = busInfoForewarningMapper.getBusInfoForewarningList(searchVo);
        forewarningEndDateCompute(busInfoForewarningVoList);
        return busInfoForewarningVoList;
    }

    /**
     * 反馈预警时间计算
     *
     * @param busInfoForewarningVoList 预警数据列表
     */
    private void forewarningEndDateCompute(List<BusInfoForewarningMapstruct.BusInfoForewarningVo> busInfoForewarningVoList) {
        // 查询预警设置数据
        List<BusForewarningSet> busForewarningSetList = baseBusForewarningSetService.list();
        Map<String, BusForewarningSet> busForewarningSetMap = busForewarningSetList.stream()
                .collect(Collectors.toMap(BusForewarningSet::getBusForewarningSetId, Function.identity()));
        busInfoForewarningVoList.forEach(busInfoForewarningVo -> {
            BusForewarningSet busForewarningSet = busForewarningSetMap.get(busInfoForewarningVo.getFeedbackPhase().name());
            int timeHour = busForewarningSet.getTimeHour();
            busInfoForewarningVo.setFeedbackForewarningEndDate(busInfoForewarningVo.getFeedbackDate().plusHours(timeHour));
        });
    }

    /**
     * 预警信息-按公司查询
     *
     * @param page     分页对象
     * @param searchVo 查询条件
     */
    public void getCompanyPageList(RequestPage<BusInfoForewarningMapstruct.ForewarningCompanyVo> page,
                                   BusInfoForewarningMapstruct.PageSearchVo searchVo) {
        busInfoForewarningMapper.getCompanyPageList(page, searchVo);
    }

    /**
     * 未接收预警详情
     *
     * @param busInfoForewarningId 预警id
     * @return NotReceiveDetailVo
     */
    public BusInfoForewarningMapstruct.NotReceiveDetailVo getNotReceiveDetail(String busInfoForewarningId) {
        BusInfoForewarningMapstruct.NotReceiveDetailVo notReceiveDetailVo = new BusInfoForewarningMapstruct.NotReceiveDetailVo();
        BusInfoForewarning busInfoForewarning = this.getById(busInfoForewarningId);
        notReceiveDetailVo.setBusInfoForewarningId(busInfoForewarning.getBusInfoForewarningId());
        notReceiveDetailVo.setFeedbackPhase(busInfoForewarning.getFeedbackPhase());
        notReceiveDetailVo.setFeedbackDate(busInfoForewarning.getFeedbackDate());
        BusiInfo busiInfo = baseBusiInfoService.getById(busInfoForewarning.getBusiInfoId());
        BeanUtils.copyProperties(busiInfo, notReceiveDetailVo);
        // 未接收预警倒计时结束时间
        int hourTime = baseBusForewarningSetService.getHourByEnumFeedbackPhase(notReceiveDetailVo.getFeedbackPhase());
        notReceiveDetailVo.setReceiveForewarningEndDate(notReceiveDetailVo.getFeedbackDate().plusHours(hourTime));
        List<BusiIndustryAssignMapstruct.BusiIndustryAssignVo> busiIndustryAssignVoList = baseBusiInfoService.getReceiveData(busInfoForewarning.getBusiInfoId());
        notReceiveDetailVo.setBusiIndustryAssignVoList(busiIndustryAssignVoList);
        return notReceiveDetailVo;
    }

    /**
     * 未反馈预警详情
     *
     * @param busInfoForewarningId 预警id
     * @return NotFeedbackDetailVo
     */
    public BusInfoForewarningMapstruct.NotFeedbackDetailVo getNotFeedbackDetail(String busInfoForewarningId) {
        BusInfoForewarningMapstruct.NotFeedbackDetailVo notFeedbackDetailVo = new BusInfoForewarningMapstruct.NotFeedbackDetailVo();
        BusInfoForewarning busInfoForewarning = this.getById(busInfoForewarningId);
        notFeedbackDetailVo.setBusInfoForewarningId(busInfoForewarning.getBusInfoForewarningId());
        notFeedbackDetailVo.setBusiPersonName(busInfoForewarning.getBusiPersonName());
        notFeedbackDetailVo.setFeedbackPhase(busInfoForewarning.getFeedbackPhase());
        notFeedbackDetailVo.setFeedbackDate(busInfoForewarning.getFeedbackDate());
        BusiInfo busiInfo = baseBusiInfoService.getById(busInfoForewarning.getBusiInfoId());
        BeanUtils.copyProperties(busiInfo, notFeedbackDetailVo);
        // 未反馈预警倒计时结束时间
        int hourTime = baseBusForewarningSetService.getHourByEnumFeedbackPhase(notFeedbackDetailVo.getFeedbackPhase());
        notFeedbackDetailVo.setFeedbackForewarningEndDate(notFeedbackDetailVo.getFeedbackDate().plusHours(hourTime));
        List<BusiIndustryAssignMapstruct.BusiIndustryAssignVo> busiIndustryAssignVoList = baseBusiInfoService.getFeedBackData(busInfoForewarning.getBusiInfoId());
        busiIndustryAssignVoList = busiIndustryAssignVoList.stream().filter(vo -> vo.getIndustryId().equals(busInfoForewarning.getIndustryMarkId())).collect(Collectors.toList());
        notFeedbackDetailVo.setBusiIndustryAssignVoList(busiIndustryAssignVoList);
        return notFeedbackDetailVo;
    }

    /**
     * 添加预警
     */
    @Transactional(rollbackFor = Exception.class)
    public void addForewarning(BusInfoForewarningMapstruct.AddForewarningVo addForewarningVo) {
        BusInfoForewarning busInfoForewarning = new BusInfoForewarning();
        if (EnumForewarningInfoClassify.NotReceiveForewarning.equals(addForewarningVo.getForewarningInfoClassify())) {
            // 未接收对象
            BusInfoNotification busInfoNotification = addForewarningVo.getBusInfoNotification();
            // 组装未接收预警数据
            busInfoForewarning.setBusiInfoId(busInfoNotification.getBusiInfoId());
            busInfoForewarning.setIndustryMarkId(busInfoNotification.getIndustryMarkId());
            busInfoForewarning.setIndustryMarkName(busInfoNotification.getIndustryMarkName());
            busInfoForewarning.setCompanyName(busInfoNotification.getCompanyName());
            busInfoForewarning.setCompanyId(busInfoNotification.getCompanyId());
            busInfoForewarning.setDataId(busInfoNotification.getBusInfoNotificationId());
            busInfoForewarning.setForewarningInfoClassify(EnumForewarningInfoClassify.NotReceiveForewarning);
            busInfoForewarning.setFeedbackPhase(EnumFeedbackPhase.PairingNotAgree);
            busInfoForewarning.setFeedbackDate(busInfoNotification.getPushDate());
            // 获取公司管理员, 未接收的预警给推送公司的管理员发短信
            CompanyEmployee companyAdminEmployee = baseCompanyEmployeeService.getCompanyAdminByCompanyId(busInfoNotification.getCompanyId());
            if (companyAdminEmployee != null) {
                busInfoForewarning.setSendMessageUserId(companyAdminEmployee.getUserId());
            }
        } else if (EnumForewarningInfoClassify.NotFeedbackForewarning.equals(addForewarningVo.getForewarningInfoClassify())) {
            // 未反馈对象
            BusInfoFeedback busInfoFeedback = addForewarningVo.getBusInfoFeedback();
            BusInfoTrack busInfoTrack = baseBusInfoTrackService.getById(busInfoFeedback.getBusInfoTrackId());
            // 组装未反馈预警数据
            busInfoForewarning.setBusiInfoId(busInfoFeedback.getBusiInfoId());
            busInfoForewarning.setIndustryMarkId(busInfoFeedback.getIndustryMarkId());
            busInfoForewarning.setIndustryMarkName(busInfoFeedback.getIndustryMarkName());
            busInfoForewarning.setCompanyId(busInfoTrack.getCompanyId());
            busInfoForewarning.setCompanyName(busInfoTrack.getCompanyName());
            busInfoForewarning.setDataId(busInfoFeedback.getBusInfoTrackId());
            busInfoForewarning.setForewarningInfoClassify(EnumForewarningInfoClassify.NotFeedbackForewarning);
            busInfoForewarning.setFeedbackPhase(busInfoFeedback.getFeedbackPhase());
            busInfoForewarning.setFeedbackDate(busInfoFeedback.getFeedbackDate());
            busInfoForewarning.setBusiPersonId(busInfoFeedback.getBusiPersonId());
            busInfoForewarning.setBusiPersonName(busInfoFeedback.getBusiPersonName());
            busInfoForewarning.setSendMessageUserId(busInfoFeedback.getBusiPersonId());
        }
        // 移除之前的预警信息和之前反馈阶段的预警定时任务
        this.removeForewarning(busInfoForewarning.getDataId());
        // 将本次反馈预警数据,添加到预警表中
        this.save(busInfoForewarning);
        // 查询预警时长配置
        int hourTime = baseBusForewarningSetService.getHourByEnumFeedbackPhase(busInfoForewarning.getFeedbackPhase());
        // corn表达式
        String cronStr = QuartzUtils.getCronStr(busInfoForewarning.getFeedbackDate().plusHours(hourTime));
        // 新增定时任务
        String jobName = busInfoForewarning.getBusInfoForewarningId();
        QuartzUtils.addJob(jobName, ForewarningJob.class, busInfoForewarning.getBusInfoForewarningId(), cronStr);
    }


    /**
     * 移除预警
     */
    @Transactional(rollbackFor = Exception.class)
    public void removeForewarning(String dataId) {
        // 根据数据dataId,取消之前反馈阶段的预警定时任务, 且将该经营信息的预警从预警表中移除
        List<BusInfoForewarning> forewarningList = this.lambdaQuery()
                .eq(BusInfoForewarning::getDataId, dataId)
                .list();
        if (ListUtils.isExistsEle(forewarningList)) {
            List<String> forewarningIdList = forewarningList.stream()
                    .map(BusInfoForewarning::getBusInfoForewarningId).collect(Collectors.toList());
            // 删除预警信息
            this.removeBatchByIds(forewarningIdList);
            // 删除定时任务
            QuartzUtils.removeJobs(forewarningIdList);
        }
    }

    /**
     * 发送预警短信
     *
     * @param forewarningSmsVo 预警短信vo
     * @return Boolean
     */
    public Boolean sendForewarningSms(BusInfoForewarningMapstruct.ForewarningSmsVo forewarningSmsVo) {
        BusInfoForewarning busInfoForewarning = this.getById(forewarningSmsVo.getBusInfoForewarningId());
        // 查询项目
        BusiInfo busiInfo = baseBusiInfoService.getById(busInfoForewarning.getBusiInfoId());
        // 设置短信参数
        Map<String, String> param = new HashMap<>(1);
        param.put("projectName", busiInfo.getProjectName());
        String paramStr = JsonUtils.objectToString(param);
        // 发送短信
        boolean sendFlag = aliSmsConfig.sendSms(forewarningSmsVo.getSmsCode(), forewarningSmsVo.getMobile(), paramStr);
        if (sendFlag) {
            // 发送成功后, 更新预警信息发送状态为已发送短信
            busInfoForewarning.setSendFlag(Boolean.TRUE);
            this.updateById(busInfoForewarning);
        }
        return sendFlag;
    }
}